from datetime import datetime
from turtle import update
from typing import Iterable, List, Union
from fastapi import FastAPI
from fastapi.routing import APIRoute
from sqlalchemy import delete, select

from app.utils.tool import safe_iterable
from .schema import RouteSchema
from .model import RouteModel
from app.dependencies.init_databases import db


class Routes():
    def __init__(self, app: FastAPI | None = None):
        self.app = app

    def init_app(self, app: FastAPI):
        '''初始化权限'''
        self.app = app

    def get_routes_running(self):
        '''同步所有路由信息'''
        routes = []
        if self.app is not None:
            for route in self.app.routes:
                route_dict = {}
                # self.routes.append(route)
                '''
                [Route(path='/openapi.json', name='openapi', methods=['GET', 'HEAD']),
                Route(path='/docs', name='swagger_ui_html',
                    methods=['GET', 'HEAD']),
                Route(path='/docs/oauth2-redirect',
                    name='swagger_ui_redirect', methods=['GET', 'HEAD']),
                Route(path='/redoc', name='redoc_html', methods=['GET', 'HEAD']),
                APIRoute(path='/admin/user/', name='list', methods=['GET']),
                APIRoute(path='/admin/user/', name='create', methods=['POST']),
                APIRoute(path='/admin/user/test', name='test', methods=['GET'])]
                '''
                if isinstance(route, APIRoute):
                    # 获取视图函数
                    endpoint = route.endpoint
                    path = route.path
                    methods = route.methods
                    tags = route.tags
                    summary = route.summary
                    description = route.description
                    route_dict = {
                        "endpoint": endpoint,
                        "path": path,
                        "methods": methods,
                        "tags": tags,
                        "summary": summary,
                        "description": description
                    }
                    routes.append(route_dict)
        return routes

    async def get_routes_db(self):
        '''获取所有路由'''
        results = await db.fetch_all(select(RouteModel))
        return [RouteSchema.model_validate(
            result) for result in results]

    async def constrast(self, routes_running: List[RouteSchema], routes_db: List[RouteSchema]):
        '''对比路由'''
        routes_db_deleteIds = [route.id for route in routes_db]
        routes_add = []
        for route_running in routes_running:
            for route_db in routes_db:
                if (
                    route_running.path == route_db.path
                    and route_running.description == route_db.description
                    and route_running.endpoint == route_db.endpoint
                    and route_running.summary == route_db.summary
                    and set(safe_iterable(route_running.tags)) == set(safe_iterable(route_db.tags))
                    and route_running.methods == route_db.methods
                ):

                    # 更新路由
                    routes_db_deleteIds.remove(route_db.id)
                    break
                else:
                    # 新增路由
                    routes_add.append(route_running)
        return routes_add, routes_db_deleteIds

    async def sync_db(self, routes_db_deleteIds: List[int], routes_add: List[RouteSchema]):
        """更新路由"""
        # 删除路由

        await db.execute(delete(RouteModel).where(RouteModel.id.in_(routes_db_deleteIds)))
        # 新增路由
        for route_add in routes_add:
            route_add.update_time = datetime.now()
        await db.execute(RouteModel.insert().values([route_add.model_dump() for route_add in routes_add]))
